﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Xml.Linq;
using System.Diagnostics;

using P2PChat.Net;
using P2PChat.Data;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace P2PChat.Server
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            RefreshRegUser();
            sysLog.FilePath = @"log\SystemLog.log";
            netLog.Show();
        }

        #region 私有成员
        /** 
         * 线程对应的功能 :
         *  
         * thread_ListViewHandler : System.Threading.Thread
         * - 负责程序ListView相关的后台操作
         * 
         * thread_NetWorker : System.Threading.Thread
         * - 负责程序的网络活动
         */
        private Thread
            thread_ListViewHandler,
            thread_NetWorker;
        private Listener listener;
        private Dictionary<Guid, string> publicKeys = new Dictionary<Guid,string>();
        private Dictionary<Guid, string> privateKeys = new Dictionary<Guid,string>();
        private P2PChat.Log.TimeStampLog sysLog = new Log.TimeStampLog();
        private P2PChat.Log.Form_Log netLog = new P2PChat.Log.Form_Log();
        public List<ClientNode> clientTable = new List<ClientNode>();
        private PacketParser parser = new PacketParser();
        
        private readonly Guid EmptyGuid = new Guid("00000000-0000-0000-0000-000000000000");

        private void RefreshRegUser()
        {
            if (thread_ListViewHandler == null)
            {
                thread_ListViewHandler = new Thread(RefreshUI_List_RegUser);
            }
            else if (thread_ListViewHandler.ThreadState == System.Threading.ThreadState.Running)
            {
                thread_ListViewHandler.Abort();
                thread_ListViewHandler = new Thread(RefreshUI_List_RegUser);
            }
            else
            {
                thread_ListViewHandler = new Thread(RefreshUI_List_RegUser);
            }
            thread_ListViewHandler.Start();

        }
        #endregion

        #region 界面操作
        private delegate string GetUserIdDelegate(int index);
        // 获取ui_List_RegUser中选中项的id
        public string GetUserId(int index)
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new GetUserIdDelegate(GetUserId), index) as string;
            }
            else
            {
                if (ui_List_RegUser.SelectedItems.Count != 0)
                {
                    if (index == -1) { return ui_List_RegUser.SelectedItems[0].SubItems[0].Text; }
                    return ui_List_RegUser.Items[index].SubItems[0].Text;
                } return "";
            }
        }

        private delegate int GetUI_RegUser_ItemCountDelegate();
        // 获取ui_List_RegUser中的项数
        public int GetUI_RegUser_ItemCount()
        {
            if (this.InvokeRequired)
            {
                return (int)this.Invoke(new GetUI_RegUser_ItemCountDelegate(GetUI_RegUser_ItemCount));
            }
            else
            {
                return ui_List_RegUser.Items.Count;
            }
        }

        private delegate ListViewItem GetUserItemDelegate(int index);
        // 获取ui_List_RegUser中选中项的条目
        public ListViewItem GetUserItem(int index)
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new GetUserItemDelegate(GetUserItem), index) as ListViewItem;
            }
            else
            {
                if (ui_List_RegUser.SelectedItems.Count != 0)
                {
                    if (index == -1) { return ui_List_RegUser.SelectedItems[0]; }
                    return ui_List_RegUser.Items[index];
                }
                else { return null; }
            }
        }

        private delegate void UI_RegUser_AddDelegate(ListViewItem item);
        /// <summary>
        /// 为"注册的用户 == ui_RegUser"列表中添加项目
        /// </summary>
        /// <param name="item"></param>
        public void UI_RegUser_Add(ListViewItem item) {
            if (this.InvokeRequired)
            {
                this.Invoke(new UI_RegUser_AddDelegate(UI_RegUser_Add), item);
            }
            else
            {
                ui_List_RegUser.Items.Add(item);
            }
        }

        private delegate void UI_RegUser_ClearDelegate();
        public void UI_RegUser_Clear()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new UI_RegUser_ClearDelegate(UI_RegUser_Clear));
            }
            else
            {
                ui_List_RegUser.Items.Clear();
            }
        }

        private delegate void UI_UserFriends_AddDelegate(ListViewItem item);
        /// <summary>
        /// 为"选中用户的好友 == ui_UserFriends"列表中添加项目
        /// </summary>
        /// <param name="item"></param>
        public void UI_UserFriends_Add(ListViewItem item)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new UI_UserFriends_AddDelegate(UI_UserFriends_Add), item);
            }
            else
            {
                ui_List_UserFriend.Items.Add(item);
            }
        }

        private delegate void UI_UserFriends_ClearDelegate();
        public void UI_UserFriend_Clear()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new UI_UserFriends_ClearDelegate(UI_UserFriend_Clear));
            }
            else
            {
                ui_List_UserFriend.Items.Clear();
            }
        }

        private delegate void ShowSelectedFriendInfoDelegate(string info);
        public void ShowSelectedFriendInfo(string info)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ShowSelectedFriendInfoDelegate(ShowSelectedFriendInfo), info);
            }
            else
            {
                lb_SelectedFriendInfo.Text = info;
            }
        }

        private delegate void ShowSelectedUserInfoDelegate(string info);
        public void ShowSelectedUserInfo(string info)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ShowSelectedUserInfoDelegate(ShowSelectedUserInfo), info);
            }
            else
            {
                lb_SelectedUserInfo.Text = info;
            }
        }

        private delegate void ShowConnectionCountDelegate(int connCount);
        /// <summary>
        /// 在状态栏显示当前的连接数量
        /// </summary>
        /// <param name="connCount"></param>
        public void ShowConnectionCount(int connCount)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ShowConnectionCountDelegate(ShowConnectionCount), connCount);
            }
            else
            {
                lb_Connections.Text = string.Format(@"当前连接数: {0}", connCount);
            }
        }

        private delegate void ShowCurrentWorkingDelegate(string currentWorking);
        /// <summary>
        /// 在状态栏显示当前进行的工作
        /// </summary>
        /// <param name="currentWorking"></param>
        public void ShowCurrentWorking(string currentWorking)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ShowCurrentWorkingDelegate(ShowCurrentWorking), currentWorking);
            }
            else
            {
                lb_Working.Text = currentWorking;
            }
        }
        #endregion

        #region thread_ListViewHandler专属方法
        private void RefreshUI_List_RegUser()
        {
            ShowCurrentWorking("正在获取注册的用户信息...");
            UI_RegUser_Clear();
            DBCDataContext dc = new DBCDataContext();

            var allUsers = dc.tb_Users.Select(x => x);
            foreach(var x in allUsers) {
                // 检查正确性
                if (x.guid != EmptyGuid)
                {
                    Guid id = x.guid;
                    string emailAddr = x.regEmail;
                    XElement perInfo = x.personInfo;
                    string nickName = "";
                    if (perInfo != null)
                    {
                        if (perInfo.Element("Nickname") != null)
                        {
                            nickName = perInfo.Element("Nickname").Value;
                        }
                    }

                    ListViewItem item = new ListViewItem(new string[] {
                        id.ToString("D"),
                        emailAddr,
                        nickName
                    });
                    UI_RegUser_Add(item);
                }
            }
            ShowCurrentWorking("就绪");
        }

        private void RefreshUI_List_SelectedFriends()
        {
            ShowCurrentWorking("正在获取选中的用户好友信息...");
            UI_UserFriend_Clear();
            DBCDataContext dc = new DBCDataContext();
            
            // 获取选中用户的好友信息 - SQL Type => xml
            Debug.WriteLine(GetUserId(-1));
            XElement xmlFriends = dc.tb_Users.First(x =>
                x.guid == new Guid(GetUserId(-1))
                ).friendList;

            if (xmlFriends != null)
            {
                if (xmlFriends.Elements("Friend") != null)
                {
                    foreach (XElement x in xmlFriends.Elements("Friend"))
                    {
                        // 直接在ui_List_RegUsers中查找
                        foreach (ListViewItem item in ui_List_RegUser.Items)
                        {
                            if (item.SubItems[0].Text == x.Attribute("id").Value)
                            {
                                UI_UserFriends_Add(item);
                                break;
                            }
                        }

                        for (int i = 0; i < GetUI_RegUser_ItemCount(); i++)
                        {
                            if (GetUserId(i) == x.Attribute("id").Value)
                            {
                                UI_UserFriends_Add(GetUserItem(i));
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                Debug.WriteLine("选中项({0})的Friend列表不存在(为空)!", GetUserId(-1));
            }
        }
        #endregion

        #region thread_NetWorker专属
        private void netWorker_Main()
        {
            listener = new Listener("0.0.0.0", 3000);
            listener.ClientConnect += new EventHandler<ListenerEventArgs>(listener_ClientConnect);
            listener.Listen();
        }

        void listener_ClientConnect(object sender, ListenerEventArgs e)
        {
            try
            {
                // 收取并解包
                BinaryFormatter bf = new BinaryFormatter();
                NetPacket packet = (NetPacket)bf.Deserialize(e.Client.GetStream());
                if (netLog != null)
                {
                    netLog.Add(string.Format(@"从{0}:{1}接收到数据包", e.IPString, e.Port));
                }

                // 分析包内容
                NetPacket retPacket = null;
                switch (packet.Tag)
                {
                    case PacketTag.Login:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is Data.Packets.LoginPacket)
                        {
                            retPacket = NetAccesser.AccessLogin(packet.Content as Data.Packets.LoginPacket, e.IP);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.LoginResult,
                                Content = new Data.Packets.LoginResultPacket()
                                {
                                    ResultCode = 2,
                                    Result = "登录数据不正确",
                                },
                            };
                        }
                        break;
                    case PacketTag.Regist:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is Data.Packets.RegistPacket)
                        {
                            retPacket = NetAccesser.AccessRegist(packet.Content as Data.Packets.RegistPacket);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.RegistResult,
                                Content = new Data.Packets.LoginResultPacket()
                                {
                                    ResultCode = 2,
                                    Result = "注册数据不正确",
                                },
                            };
                        }
                        break;
                    case PacketTag.ApplyPersonalInfo:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is Data.Packets.ApplyPersonalInfoPacket)
                        {
                            retPacket = NetAccesser.AccessApplyPersonalInfo(packet.Content as Data.Packets.ApplyPersonalInfoPacket);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.ApplyPersonalInfo,
                                Content = new Data.Packets.RawStringPacket()
                                {
                                    Content = "服务器收到的数据不正确,无法处理!",
                                },
                            };
                        }
                        break;
                    case PacketTag.SearchFriend:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is Data.Packets.SearchFriendPacket)
                        {
                            retPacket = NetAccesser.AccessSearchFriend(packet.Content as Data.Packets.SearchFriendPacket);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.SearchFriend,
                                Content = new P2PChat.Data.Packets.SearchFriendResultPacket()
                                {
                                    ResultXml = new XElement("SearchResult"),
                                },
                            };
                        }
                        break;
                    case PacketTag.ApplyAddFriend:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is P2PChat.Data.Packets.ApplyAddFriendPacket)
                        {
                            retPacket = NetAccesser.AccessApplyAddFriend(packet.Content as P2PChat.Data.Packets.ApplyAddFriendPacket);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.SearchFriend,
                                Content = new P2PChat.Data.Packets.ApplyAddFriendResultPacketcs()
                                {
                                    ResultString = "未能正确解析请求的好友信息",
                                },
                            };
                        }
                        break;
                    case PacketTag.GetValue:
                        if (netLog != null)
                        {
                            netLog.Add(string.Format(@"从{0}:{1}接收到的内容是:{2}", e.IPString, e.Port, packet.Tag));
                        }
                        if (packet.Content is P2PChat.Data.Packets.GetUserIPEndPointPacket)
                        {
                            retPacket = NetAccesser.AccessGetUserIP(packet.Content as P2PChat.Data.Packets.GetUserIPEndPointPacket);
                        }
                        else
                        {
                            retPacket = new NetPacket()
                            {
                                Tag = PacketTag.GetValue,
                                Content = new P2PChat.Data.Packets.GetUserIPEndPointPacket()
                                {
                                    RemoteUserId = (packet.Content as P2PChat.Data.Packets.GetUserIPEndPointPacket).RemoteUserId,
                                    IPAddress = "",
                                    Port = -1,
                                },
                            };
                        }
                        break;
                }

                // 回发数据包
                if (retPacket != null)
                {
                    if (netLog != null)
                    {
                        netLog.Add(string.Format(@"生成向{0}:{1}发送的数据包", e.IPString, e.Port));
                    }
                    MemoryStream ms = new MemoryStream();
                    bf.Serialize(ms, retPacket);
                    e.Client.Client.Send(ms.GetBuffer());

                    if (netLog != null)
                    {
                        netLog.Add(string.Format(@"向{0}:{1}发送数据包", e.IPString, e.Port));
                    }
                }
            }
            catch (Exception ex)
            {
                if (netLog != null)
                {
                    netLog.Add("捕获到异常:" + ex.Message);
                }
                NetPacket exPacket = new NetPacket()
                {
                    Tag = PacketTag.ServerException,
                    Content = null,
                };
                MemoryStream ms = new MemoryStream();
                new BinaryFormatter().Serialize(ms, exPacket);
                e.Client.Client.Send(ms.GetBuffer());
            }
        }

        

        
        #endregion

        #region 测试用代码
        private delegate void __FunctionDelegate();
        public void __Function()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new __FunctionDelegate(__Function));
            }
            else
            {

            }
        }
        #endregion

        #region 事件
        private void ui_List_RegUser_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ui_List_RegUser.SelectedItems.Count == 0) { return; }
            if (thread_ListViewHandler == null)
            {
                thread_ListViewHandler = new Thread(RefreshUI_List_SelectedFriends);
            }
            else if (thread_ListViewHandler.ThreadState == System.Threading.ThreadState.Running)
            {
                thread_ListViewHandler.Abort();
                thread_ListViewHandler = new Thread(RefreshUI_List_SelectedFriends);
            }
            else
            {
                thread_ListViewHandler = new Thread(RefreshUI_List_SelectedFriends);
            }
            thread_ListViewHandler.Start();
        }

        private void 退出ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (thread_ListViewHandler != null) thread_ListViewHandler.Abort();
            if (thread_NetWorker != null) thread_NetWorker.Abort();
            Application.Exit();
        }

        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RefreshRegUser();
            UI_UserFriend_Clear();
        }

        private void 启动ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listener != null)
            {
                if (MessageBox.Show("服务已经启动,是否重新启动?", "提示", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {

                    thread_NetWorker = new Thread(netWorker_Main);
                    listener.Stop();

                    thread_NetWorker.Start();
                }
            }
            else
            {
                thread_NetWorker = new Thread(netWorker_Main);
                thread_NetWorker.Start();
            }
        }

        private void 停止ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            thread_NetWorker.Abort();
        }
        #endregion
    }
}
